package com.wxsm.wechat.util;

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.util.ReflectionUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created with Yang Huan
 * Date: 2017/3/2
 * Time: 11:34
 */
public class CommonUtil {

    private static final SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");

    public static String argumentsToString(Object... args) {
        if (args == null || args.length == 0) {
            return "";
        }

        try {
            StringBuilder buffer = new StringBuilder();
            for (int i = 0; i < args.length; i++) {
                if (args[i] == null || args[i].getClass().getTypeName().contains("springframework")) {
                    continue;
                }
                if (i > 0) {
                    buffer.append(",");
                }
                buffer.append("arg").append(i + 1).append(":").append(args[i].getClass().getName().substring(args[i].getClass().getName().lastIndexOf(".") + 1)).append("(");
                if (args[i].getClass().isPrimitive() || args[i] instanceof Number || args[i] instanceof Character || args[i] instanceof Boolean || args[i] instanceof String) {
                    buffer.append(args[i].toString());
                } else if (args[i] instanceof Enum) {
                    buffer.append(((Enum) args[i]).name());
                } else {
                    List<Field> fields = new ArrayList<>();
                    Class<?> clazz = args[i].getClass();
                    for (; !(clazz == Object.class); clazz = clazz.getSuperclass()) {
                        fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
                    }
                    int j = 0;
                    for (Field field : fields) {
                        if ("serialVersionUID".contains(field.getName())) {
                            continue;
                        }
                        field.setAccessible(true);
                        Object v = ReflectionUtils.getField(field, args[i]);
                        if (v != null && !v.toString().equals("")) {
                            if (j > 0) {
                                buffer.append(",");
                            }
                            buffer.append(field.getName()).append(":");
                            if (field.getType().equals(Date.class)) {
                                buffer.append(df.format(v));
                            } else {
                                buffer.append(v.toString());
                            }
                            j++;
                        }
                    }
                }
                buffer.append(")");
            }
            return buffer.toString();
        } catch (Exception e) {
            return "parse argument error:" + e.getClass().getName();
        }
    }

    public static String[] getNullPropertyNames(Object source) {
        BeanWrapper src = new BeanWrapperImpl(source);
        PropertyDescriptor[] pds = src.getPropertyDescriptors();
        Set<String> emptyNames = new HashSet<>();
        for (PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }
}
